#include "key3.h"
#include "key_common.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "control.h"

#define GPIO_CHIP_LABEL "GPIOF"
#define GPIO_LINE 8
#define VOLUME_DECREMENT_PERCENTAGE 10 // 每次减少的音量百分比
#define CONSUMER "key3"

typedef struct
{
    const char *card;
    const char *selem;
} key3_thread_args_t;

/**
 * 减少音量
 * @param card: 声卡名称
 * @param selem: 控制项名称
 */
static void decrease_volume(const char *card, const char *selem)
{
    long current_volume;
    long min_volume, max_volume;

    // 获取当前音量
    current_volume = get_playback_volume(card, selem);
    if (current_volume < 0)
    {
        fprintf(stderr, "Failed to get current playback volume\n");
        return;
    }

    // 获取音量范围
    if (get_playback_volume_range(card, selem, &min_volume, &max_volume) < 0)
    {
        fprintf(stderr, "Failed to get playback volume range\n");
        return;
    }

    // 计算新的音量
    long volume_decrement = (max_volume - min_volume) * VOLUME_DECREMENT_PERCENTAGE / 100;
    long new_volume = current_volume - volume_decrement;
    if (new_volume < min_volume)
    {
        new_volume = min_volume;
    }

    // 设置新的音量
    int err = set_playback_volume(card, selem, &new_volume);
    if (err < 0)
    {
        fprintf(stderr, "Failed to set playback volume: %s\n", snd_strerror(err));
        return;
    }

    // 重新获取当前音量
    current_volume = get_playback_volume(card, selem);
    if (current_volume < 0)
    {
        fprintf(stderr, "Failed to get current playback volume after setting new volume\n");
        return;
    }

    printf("Playback volume decreased to %ld (max %ld)\n", current_volume, max_volume);
}

/**
 * 处理按键3状态变化
 * @param line: GPIO线指针
 * @param last_value: 上一次的按键状态
 * @param card: 声卡名称
 * @param selem: 控制项名称
 */
static void handle_key_event(struct gpiod_line *line, int *last_value, const char *card, const char *selem)
{
    int value = gpiod_line_get_value(line);

    if (value != *last_value)
    {
        if (value == 0)
        {
            printf("按键3按下，减少音量\n");
            decrease_volume(card, selem);
        }
        else
        {
            printf("按键3释放\n");
        }
        *last_value = value;
    }
}

/**
 * 按键3控制线程函数
 * @param args: 线程参数
 * @return: NULL
 */
static void *key3_thread_func(void *args)
{
    key3_thread_args_t *thread_args = (key3_thread_args_t *)args;

    // 初始化GPIO按键
    struct gpiod_line *line = gpio_init(GPIO_CHIP_LABEL, GPIO_LINE, CONSUMER);
    if (!line)
    {
        free(thread_args);
        return NULL;
    }

    pthread_detach(pthread_self()); // 在资源初始化后分离线程

    // 获取初始按键状态
    int last_value = gpiod_line_get_value(line);

    // 持续监控按键状态
    while (1)
    {
        handle_key_event(line, &last_value, thread_args->card, thread_args->selem);
        usleep(100000); // 延迟100毫秒
    }

    // 关闭GPIO芯片
    gpiod_chip_close(gpiod_line_get_chip(line));
    free(thread_args); // 释放动态分配的内存
    return NULL;
}

/**
 * 按键3控制
 * @param card: 声卡名称
 * @param selem: 控制项名称
 */
void key3_control(const char *card, const char *selem)
{
    pthread_t key3_thread;
    key3_thread_args_t *args = (key3_thread_args_t *)malloc(sizeof(key3_thread_args_t));
    if (!args)
    {
        perror("内存分配失败");
        return;
    }

    args->card = card;
    args->selem = selem;

    // 创建按键3控制线程
    if (pthread_create(&key3_thread, NULL, key3_thread_func, args) != 0)
    {
        perror("创建按键3控制线程失败");
        free(args); // 如果线程创建失败，释放内存
        return;
    }
}
